#ifndef __BLOCK_H__
#define __BLOCK_H__

#include <iostream>
#include <fstream>
#include <vector>

#include "./includes/register_pack.h"

class Block{
	private:
		unsigned int blockSize;
	private:
		bool fchained;
		bool fchain_begining;
		bool fchain_end;
		unsigned short quantity;//cantidad de registros en el bloque
		std::vector <unsigned short> reg_number;
		std::vector <unsigned short> reg_offset;
		std::vector <char*> reg;
		const RegisterFactory& rf;
				
	private:
		static const char BLOCK_IS_CHAINED 		  = 0x01; /* bit 0 on */
		static const char BLOCK_IS_CHAIN_BEGINING = 0x02; /* bit 1 on */
		static const char BLOCK_IS_CHAIN_END 	  = 0x04; /* bit 2 on */
		
	public:
		//crea un bloque vacio
		Block(const RegisterFactory& regFactory,const unsigned int blockSize);
		~Block();
		
		//Devuelve la cantidad de espacio libre
		unsigned short getFree();
		//Devuelve la cantidad de registros en el bloque
		unsigned short getQuantity();
		//Devuelve

		//Agrega un registro al bloque, devuelve el nro de registro dentro del bloque
		unsigned short addRegister(const Register &reg, unsigned short reg_num = 0);
		//Devuelve un puntero al registro cuyo número fué pasado por parámetro(NULL si no existe)
		Register *getRegister(const unsigned short number);
		//elimina un registro del bloque
		void removeRegister(const unsigned short number);
		
		unsigned short getRegOffset(unsigned int i){ return reg_offset[i]; }
		unsigned short getRegNumber(unsigned int i){ return reg_number[i]; }
		char* getReg(unsigned int i){ return reg[i]; }

		/* Pasa las variables booleanas al char */
		char getStatus()const;
		/* Pasa los flags a las variables booleanas */
		void setStatus(char status);

		bool isChained()const{ return fchained; }
		bool isChainBegining()const{ return fchain_begining; }
		bool isChainEnd()const{ return fchain_end; }

		void setChained(bool state){ this->fchained = state; }
		void setChainBegining(bool state){ this->fchain_begining = state; }
		void setChainEnd(bool state){ this->fchain_end = state; }
		
		
		static unsigned int getHeaderSize(){ return (sizeof(unsigned short)+sizeof(char)); }
		static unsigned int getDataControlSize(){ return (sizeof(unsigned short int)*2); }
		
		static bool isChainedBit(char status){ return (status&BLOCK_IS_CHAINED); }
	private:
		//Devuelve el nro de registro mas chico no utilizado		
		unsigned short findMin();
};

#endif /* __BLOCK_H__ */
